'''
Created on May 18, 2011

@author: Adam Matysiak
'''

class TDL(object):
	def __init__(self, conf):
		self.conf = conf

		assert isinstance(self.conf, dict)
		assert self.conf.has_key('screenspec') == True

		self.test_cases = []

	def add_testcase(self, ucid, name):
		t = TestCase(self.conf, self, ucid, name)
		self.test_cases.append(t)

		return t
	
	def add_ready_testcase(self, tc):
		self.test_cases.append(tc)
		return tc

	def get_test_cases(self):
		return self.test_cases

	def as_text(self):
		return "\n".join([tc.as_text() for tc in self.test_cases])
	
class TestCase(object):
	def __init__(self, conf, tdl, ucid, name):
		self.conf = conf

		self.tdl = tdl
		self.ucid = ucid
		self.name = name
		self.conditions = []
		self.steps = []

	def generate_tid(self, full = True):
		if full:
			tid = "TESTCASE TC%d" % (self.ucid)
		else:
			tid = "TC%d" % (self.ucid)
		
		before = 0
		after = 0
		is_after = False
		for tc in self.tdl.get_test_cases():
			if tc.get_ucid() != self.get_ucid():
				continue
			elif tc.get_name() == self.get_name():
				is_after = True
			else:
				if is_after == True:
					after = after + 1
				else:
					before = before + 1					
	
		if before > 0 or after > 0:
			tid += "_%d" % (before + 1)
		
		return tid

	def add_precondition(self, tc):
		c = Condition(self.conf, tc)
		self.conditions.append(c)

	def add_step(self, step, screen):
		conf = self.conf
		conf['uc'] = self.ucid
		conf['step'] = step
		conf['screen'] = screen
		
		ts = TestStep(conf)
		self.steps.append(ts)
		return ts	
	
	def as_text(self):
		result  = "%s. %s\n" % (self.generate_tid(), self.name)

		result += "PRECONDITION"
		if len(self.conditions) != 0:
			result += "".join([" %s," % condition.as_text() for condition in self.conditions])
			result = result[:-1]

		result += "\n"
		
		if len(self.steps) != 0:
			result += "".join([step.as_text() for step in self.steps])

		return result
	
	def get_id(self, full = True):
		return self.generate_tid(full)
	
	def get_name(self):
		return self.name
	
	def get_ucid(self):
		return self.ucid
	
	def get_usecase(self):
		fuse = self.conf['fuse']
		return fuse.get_usecase(self.ucid)

class Condition(object):
	def __init__(self, conf, tc):
		self.tc = tc
		
	def as_text(self):
		return "%s" % (self.tc.get_id(False))
		
class TestStep(object):
	def __init__(self, conf):
		self.conf = conf
		self.uc = conf['uc']
		self.step = conf['step']
		self.screen = conf['screen']
		self.actions = []

	def add_action(self, action, field, value = None, extra = None):
		if action.upper() == "Click".upper():
			a = Click(self.conf, field)
		elif action.upper() == "Check".upper():
			a = Check(self.conf, field, value)
		elif action.upper() == "Set".upper():
			a = Set(self.conf, field, value, extra)
		elif action.upper() == "Select".upper():
			a = Select(self.conf, field, value)
		
		self.actions.append(a)
		return a
	
	def get_usestep(self):
		fuse = self.conf['fuse']
		uc = fuse.get_usecase(self.ucid)
		if uc != None:
			return uc.get_step(self.step)
		return None

	def as_text(self):
		result = "\tTESTSTEP UC%s.%s(%s):\n" % (self.uc, self.step, self.screen)
		result += "".join(["\t\t%s\n" % action.as_text() for action in self.actions])		
		return result

class Action(object):
	def __init__(self, conf, field):
		self.conf = conf
		self.field = field

class Check(Action):
	def __init__(self, conf, field, value = None):
		super(Check, self).__init__(conf, field)
		self.value = value
		self.components = []	
	
	def add_for_index(self, selected, label = '', value = ''):
		c = Compound(self.conf, "", selected, label, value)
		self.components.append(c)
		return c		
	
	def add_for_index_value(self, value):
		c = Compound(self.conf, "", "", "", value)
		self.components.append(c)
		return c
	
	def add_for_one_index(self, label = '', value = ''):
		c = Compound(self.conf, "ONE", "", label, value)
		self.components.append(c)
		return c
	
	def add_for_any_index(self):
		c = Compound(self.conf, "ANY", "", "", "")
		self.components.append(c)
		return c
	
	def add_for_all_index(self):
		c = Compound(self.conf, "ALL", "", "", "")
		self.components.append(c)
		return c
	
	def add_for_every_index(self):
		c = Compound(self.conf, "EVERY", "", "", "")
		self.components.append(c)
		return c
	
	def add_pos(self, field, value):
		f = Func(self.conf, "POS", field, value)
		self.components.append(f)
		return f
	
	def add_selected(self, field):
		f = Func(self.conf, "SELECTED", field, None)
		self.components.append(f)
		return f
	
	def add_count(self, field = None):
		f = Func(self.conf, "COUNT", field, None)
		self.components.append(f)
		return f
	
	def add_val(self, field, value = None):
		f = Func(self.conf, "VAL", field, value)
		self.components.append(f)
		return f
	
	def add_sorted(self, value = ''):
		f = Func(self.conf, "SORTED", None, value)
		self.components.append(f)
		return f
	
	def as_text(self):
		if self.value == None:			
			result = "CHECK %s:\n" % (self.field)
			result += "".join(["%s" % component.as_text() for component in self.components])
			return result
		else:
			return "CHECK %s=\"%s\"" % (self.field, self.value)

class Compound:
	def __init__(self, conf, quantifier, selected, label, value):
		self.conf = conf
		self.quantifier = quantifier
		self.selected = selected
		self.label = label
		self.value = value
		self.actions = []
	
	def add_action(self, action, field, value = ''):
		if action.upper() == "Check".upper():
			a = Check(self.conf, field, value)
			self.actions.append(a)
		
	def as_text(self):
		quant = ""
		if self.quantifier != "":
			quant = " %s" % (self.quantifier)
		
		selected = ""		
		if self.selected != "":
			selected = "%s" % (self.selected)
			
		label = ""
		if self.label == "labeled":
			label = " LABELED AS"
		elif self.label == "stored":
			label = " STORED AS"
			
		value = ""
		if self.value != "":
			value = " %s" % (self.value)
			
		result = "\t\t\tFOR%s INDEX%s%s%s:\n" % (quant, selected, label, value)
		result += "".join(["\t\t\t\t%s\n" % action.as_text() for action in self.actions])
		return result[:-1]

class Func:
	def __init__(self, conf, type, field, value):
		self.conf = conf
		self.type = type
		self.field = field
		self.value = value
		
	def as_text(self):
		func = self.type
		if self.field != "":
			func += "(\"%s\")" % (self.field)
		
		if self.value != None:
			if self.type == "SORTED":
				func += " %s" % (self.value)
			else:
				func += "%s" % (self.value)
		
		return "\t\t\t%s\n" % (func)

class Click(Action):
	def __init__(self, conf, field):
		super(Click, self).__init__(conf, field)
	
	def as_text(self):
		return "CLICK %s" % (self.field)

class Set(Action):
	def __init__(self, conf, field, value, is_checkbox = None):
		super(Set, self).__init__(conf, field)
		self.value = value
		self.is_checkbox= is_checkbox
	
	def as_text(self):
		if self.is_checkbox != None:
			check = "CHECKED"
			if check == False:
				check = "UN%s" % (self.is_checkbox)
				
			if type(self.value) is type([]) and self.value != []:
				result = "SET %s %s(" % (check, self.field)
				for v in self.value:
					result += "\"%s\", " % (v)
				result = result[:-2]
				return "%s)" % (result)
			else:			
					
				return "SET %s %s" % (check, self.field)
		else:
			return "SET %s=\"%s\"" % (self.field, self.value)

class Select(Action):
	def __init__(self, conf, field, value):
		super(Select, self).__init__(conf, field)
		self.value = value
	
	def as_text(self):
		if type(self.value) is type([]) and self.value != []:
			result = "SELECT %s(" % (self.field)
			for v in self.value:
				result += "\"%s\", " % (v)
			result = result[:-2]
			return "%s)" % (result)
		else:
			return "SELECT %s=\"%s\"" % (self.field, self.value)
